function Initializetables()

	//GAMEMODE.Config.pocketitems = 15
	MsgAll("and so... it begins")

	if !sql.TableExists(SteamLookup) then
		Msg(" creating SteamLookup ")
		sql.Query("CREATE TABLE SteamLookup ( ID INTEGER PRIMARY KEY, steamID varchar )")
	end

	if !sql.TableExists(Inventory) then
		Msg(" creating Inventory ")
		sql.Query("CREATE TABLE Inventory ( itemID INTEGER PRIMARY KEY, ID int, class varchar, model varchar, SID varchar, amount varchar, wepkey varchar, wasowned int, labprice int, storedmoney int, weaponclass varchar, vehiclescript varchar , clip1 int, clip2 int)" )
	end

	if !sql.TableExists(PlayerInfo) then
		Msg(" creating PlayerInfo")
		sql.Query("CREATE TABLE PlayerInfo ( ID int, rpname varchar, jailtime varchar, wallet varchar, bank varchar, stash int )" )
	end

	if !sql.TableExists(PlayerStats) then
		Msg(" creating PlayerStats")
		sql.Query("CREATE TABLE PlayerStats ( ID int, agility int, agilityexp int, acrobatics int, acrobaticsexp int, barter int, barterexp int, defense int, defenseexp int, respect int)" )
	end

	if !sql.TableExists(OwnedCars) then
		Msg(" creating OwnedCars")
		sql.Query("CREATE TABLE OwnedCars ( ID int, carname varchar)" )
	end
end





function loadstats( ply )
 	
	
	Initializetables()
	if !sql.Query("SELECT * FROM SteamLookup WHERE steamID = '" .. ply:SteamID() .."'") then
		sql.Query("INSERT INTO SteamLookup ( steamID ) VALUES ( '".. ply:SteamID() .."' )")
	end

	loadInventory(ply)
	loadPlayerInfo(ply)
	loadPlayerStats(ply)
	loadOwnedCars(ply)
	
end

function PlayerDisconnected( ply )

	saveInventory(ply)
	savePlayerInfo(ply)
	savePlayerStats(ply)
	saveOwnedCars(ply)
end






function restartSQLstructure()
	Msg(" clearing tables... ")
	sql.Query("DROP TABLE SteamLookup")
	sql.Query("DROP TABLE Inventory")
	sql.Query("DROP TABLE PlayerStats")
	sql.Query("DELETE FROM SteamLookup")
	sql.Query("DELETE FROM Inventory")
	sql.Query("DELETE FROM PlayerStats")

	Initializetables()
	for k,v in pairs(player.GetAll()) do
		sql.Query("INSERT INTO SteamLookup ( steamID ) VALUES ( '".. v:SteamID() .."' )")
		saveInventory(v)
		savePlayerInfo(v)
		savePlayerStats(v)
		saveOwnedCars(v)
	end
end

concommand.Add("sql_mulligan", restartSQLstructure)


function steamLookup(ply)
	return sql.Query("SELECT ID FROM SteamLookup WHERE steamID='"..ply:SteamID().."'")[1]['ID']
end


function dbInventoryCount(ply)
	local ID = steamLookup(ply)
	return tonumber(sql.Query("SELECT COUNT(*) FROM Inventory WHERE ID = '"..ID.."' ")[1]['COUNT(*)'])
end




function saveInventory(ply)
	local ID = steamLookup(ply)
	local Inv = ply:GetTable().Inventory or {}
	sql.Query("DELETE FROM Inventory WHERE ID = '"..ID.."' ")
	for i=1, #Inv do
		local Item=Inv[i]
		sql.Query("INSERT INTO Inventory ( 'ID', 'class', 'model', 'amount', 'wepkey', 'wasowned', 'labprice', 'storedmoney', 'weaponclass', 'vehiclescript', 'clip1', 'clip2' ) VALUES ( '"..ID.."' , '"..Item.class.."' , '"..Item.model.."' , "..Item.amount.." , "..Item.wepkey.." , "..Item.wasowned.." , "..Item.labprice.." , "..Item.storedmoney.." , '"..Item.weaponclass.."' , '"..Item.vehiclescript.."' , "..Item.clip1.." , "..Item.clip2.." )")
	end
end

function saveOwnedCars(ply)
	local ID = steamLookup(ply)
	local Cars = ply:GetTable().OwnedCars
	sql.Query("DELETE FROM OwnedCars WHERE ID = '"..ID.."' ")
	for i=1, #Cars do
		local carname=Cars[i]
		sql.Query("INSERT INTO OwnedCars ( 'ID', 'carname') VALUES ( '"..ID.."' , '"..carname.."' )")
	end
end

function savePlayerStats(ply)
	local ID = steamLookup(ply)
	local pStats = ply:GetTable().Playerstats or {agility=1, agilityexp=1, acrobatics=1, acrobaticsexp=1, barter=1, barterexp=1, defense=1, defenseexp=1, respect=1}
	// Not a word.  It is not moreso effecient enough to update it instead of delete/insert for me to be arsed to retype this
	sql.Query("DELETE FROM PlayerStats WHERE ID = '"..ID.."' ")
	sql.Query("INSERT INTO PlayerStats ( 'ID', 'agility', 'agilityexp', 'acrobatics', 'acrobaticsexp', 'barter', 'barterexp', 'defense', 'defenseexp', 'respect' ) VALUES ( '"..ID.."' , "..pStats.agility.." , "..pStats.agilityexp.." , "..pStats.acrobatics.." , "..pStats.acrobaticsexp.." , "..pStats.barter.." , "..pStats.barterexp.." , "..pStats.defense.." , "..pStats.defenseexp.." , "..pStats.respect.." )")
end

function savePlayerInfo(ply)
	local ID = steamLookup(ply)
	local pInfo = ply:GetTable().PlayerInfo or {rpname="Neua Bea", jailtime = 0, wallet = 300, bank = 3000, stash = 0 }
	// Not a word.  It is not moreso effecient enough to update it instead of delete/insert for me to be arsed to retype this
	sql.Query("DELETE FROM PlayerInfo WHERE ID = '"..ID.."' ")
	sql.Query("INSERT INTO PlayerInfo ( 'ID', 'rpname', 'jailtime', 'wallet', 'bank', 'stash' ) VALUES ( '"..ID.."' , '"..pInfo.rpname.."' , "..pInfo.jailtime.." , "..pInfo.wallet.." , "..ply:GetTable().bankBalance.." , "..pInfo.stash.." )")
end



function loadInventory(ply)

	local ID = steamLookup(ply)
	local InvLoadingTable = sql.Query("SELECT * FROM Inventory WHERE ID = '"..ID.."' ")

	if not InvLoadingTable then return end
	//Msg(sql.LastError())
	
	//if print(InvLoadingTable) then print(InvLoadingTable) end
	//if PrintTable(InvLoadingTable) then PrintTable(InvLoadingTable) end

	ply:GetTable().Inventory = ply:GetTable().Inventory or {}

	for i=1, #InvLoadingTable do

		ply:GetTable().Inventory[i] = ply:GetTable().Inventory[i] or {}

		ply:GetTable().Inventory[i].class 			= InvLoadingTable[i]['class']
		ply:GetTable().Inventory[i].model 			= InvLoadingTable[i]['model']
		ply:GetTable().Inventory[i].amount 			= tonumber(InvLoadingTable[i]['amount'])
		ply:GetTable().Inventory[i].wepkey 			= tonumber(InvLoadingTable[i]['wepkey'])
		ply:GetTable().Inventory[i].wasowned 		= tonumber(InvLoadingTable[i]['wasowned'])
		ply:GetTable().Inventory[i].labprice 		= tonumber(InvLoadingTable[i]['labprice'])
		ply:GetTable().Inventory[i].storedmoney 	= tonumber(InvLoadingTable[i]['storedmoney'])
		ply:GetTable().Inventory[i].weaponclass 	= InvLoadingTable[i]['weaponclass']
		ply:GetTable().Inventory[i].vehiclescript 	= InvLoadingTable[i]['vehiclescript']
		ply:GetTable().Inventory[i].clip1 			= tonumber(InvLoadingTable[i]['clip1'])
		ply:GetTable().Inventory[i].clip2 			= tonumber(InvLoadingTable[i]['clip2'])
	end
end

function loadOwnedCars(ply)

	local ID = steamLookup(ply)
	local CarLoadingTable = sql.Query("SELECT * FROM OwnedCars WHERE ID = '"..ID.."' ")

	if not CarLoadingTable then return end
	//Msg(sql.LastError())
	
	//if print(CarLoadingTable) then print(CarLoadingTable) end
	//if PrintTable(CarLoadingTable) then PrintTable(CarLoadingTable) end

	ply:GetTable().OwnedCars = ply:GetTable().OwnedCars or {}

	for i=1, #CarLoadingTable do

		ply:GetTable().OwnedCars[i] = ply:GetTable().OwnedCars[i] or ""

		ply:GetTable().OwnedCars[i] 			= CarLoadingTable[i]['carname']
	end
end

function loadPlayerInfo(ply)

	local ID = steamLookup(ply)
	local InfoLoadingTable = sql.Query("SELECT * FROM PlayerInfo WHERE ID = '"..ID.."' ")

	if not InfoLoadingTable then return end
	//Msg(sql.LastError())
	
	//if print(InfoLoadingTable) then print(InfoLoadingTable) end
	//if PrintTable(InfoLoadingTable) then PrintTable(InfoLoadingTable) end

	ply:GetTable().PlayerInfo = ply:GetTable().PlayerInfo or {}

	//for i=1, #InfoLoadingTable do

		ply:GetTable().PlayerInfo.rpname 		= InfoLoadingTable[1]['rpname']
		ply:GetTable().PlayerInfo.jailtime 		= tonumber(InfoLoadingTable[1]['jailtime'])
		ply:GetTable().PlayerInfo.wallet 		= tonumber(InfoLoadingTable[1]['wallet'])
		ply:GetTable().bankBalance 				= tonumber(InfoLoadingTable[1]['bank'])
		ply:GetTable().PlayerInfo.stash 		= tonumber(InfoLoadingTable[1]['stash'])
	//end
end

function loadPlayerStats(ply)
	local ID = steamLookup(ply)
	local StatsLoadingTable = sql.Query("SELECT * FROM PlayerStats WHERE ID = '"..ID.."' ")

	if not StatsLoadingTable then return end
	ply:GetTable().Playerstats = ply:GetTable().Playerstats or {}


		ply:GetTable().Playerstats.agility 			= tonumber(StatsLoadingTable[1]['agility'])
		ply:GetTable().Playerstats.agilityexp 		= tonumber(StatsLoadingTable[1]['agilityexp'])
		ply:GetTable().Playerstats.acrobatics 		= tonumber(StatsLoadingTable[1]['acrobatics'])
		ply:GetTable().Playerstats.acrobaticsexp 	= tonumber(StatsLoadingTable[1]['acrobaticsexp'])
		ply:GetTable().Playerstats.barter 			= tonumber(StatsLoadingTable[1]['barter'])
		ply:GetTable().Playerstats.barterexp 		= tonumber(StatsLoadingTable[1]['barterexp'])
		ply:GetTable().Playerstats.defense 			= tonumber(StatsLoadingTable[1]['defense'])
		ply:GetTable().Playerstats.defenseexp 		= tonumber(StatsLoadingTable[1]['defenseexp'])
		ply:GetTable().Playerstats.respect 			= tonumber(StatsLoadingTable[1]['respect'])


	timer.Simple(3, function()
		net.Start("sendStats")
			net.WriteString("all")
			net.WriteTable(ply:GetTable().Playerstats)
		net.Send(ply)
	end)
	//PrintTable(StatsLoadingTable)
end

concommand.Add("sql_mulligan", restartSQLstructure)

//hook.Add( "PlayerDisconnected", "PlayerDisconnected", PlayerDisconnected )
hook.Add( "PlayerSpawn", "statsysinitspawnstatload", loadstats )